home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 15 / Amiga Plus Leser CD 15.iso / Tools / Development / MosaicSRC / libwww2 / Unused / HTAAProt.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-03-13  |  14.1 KB  |  532 lines

  1.  
  2. /* MODULE                            HTAAProt.c
  3. **        PROTECTION FILE PARSING MODULE
  4. **
  5. ** AUTHORS:
  6. **    AL    Ari Luotonen    luotonen@dxcern.cern.ch
  7. **
  8. ** HISTORY:
  9. **
  10. **
  11. ** BUGS:
  12. **
  13. **
  14. */
  15.  
  16. #include <string.h>
  17. #include <pwd.h>    /* Unix password file routine: getpwnam()    */
  18. #include <grp.h>    /* Unix group file routine: getgrnam()        */
  19.  
  20. #include "HTUtils.h"
  21. #include "HTAAUtil.h"
  22. #include "HTAAFile.h"
  23. #include "HTLex.h"    /* Lexical analysor    */
  24. #include "HTAssoc.h"    /* Association list    */
  25. #include "HTAAProt.h"    /* Implemented here    */
  26.  
  27.  
  28. /*
  29. ** Protection setup caching
  30. */
  31. typedef struct {
  32.     char *    prot_filename;
  33.     HTAAProt *    prot;
  34. } HTAAProtCache;
  35.  
  36. PRIVATE HTList *  prot_cache    = NULL;    /* Protection setup cache.    */
  37. PRIVATE HTAAProt *default_prot    = NULL;    /* Default protection.        */
  38. PRIVATE HTAAProt *current_prot    = NULL;    /* Current protection mode    */
  39.                                         /* which is set up by callbacks    */
  40.                                         /* from the rule system when    */
  41.                                         /* a "protect" rule is matched.    */
  42.  
  43.  
  44.  
  45. /* PRIVATE                            isNumber()
  46. **        DOES A CHARACTER STRING REPRESENT A NUMBER
  47. */
  48. PRIVATE BOOL isNumber ARGS1(CONST char *, s)
  49. {
  50.     CONST char *cur = s;
  51.  
  52.     if (!s || !*s) return NO;
  53.  
  54.     while (*cur) {
  55.     if (*cur < '0' || *cur > '9')
  56.         return NO;
  57.     cur++;
  58.     }
  59.     return YES;
  60. }
  61.  
  62.  
  63. /* PUBLIC                            HTAA_getUid()
  64. **        GET THE USER ID TO CHANGE THE PROCESS UID TO
  65. ** ON ENTRY:
  66. **    No arguments.
  67. **
  68. ** ON EXIT:
  69. **    returns    the uid number to give to setuid() system call.
  70. **        Default is 65534 (nobody).
  71. */
  72. PUBLIC int HTAA_getUid NOARGS
  73. {
  74.     struct passwd *pw = NULL;
  75.  
  76.     if (current_prot  &&  current_prot->uid_name) {
  77.     if (isNumber(current_prot->uid_name)) {
  78.         if (NULL != (pw = getpwuid(atoi(current_prot->uid_name)))) {
  79.         if (TRACE) fprintf(stderr, 
  80.                    "%s(%s) returned (%s:%s:%d:%d:...)\n",
  81.                    "HTAA_getUid: getpwuid",
  82.                    current_prot->uid_name,
  83.                    pw->pw_name, pw->pw_passwd,
  84.                    pw->pw_uid, pw->pw_gid);
  85.         return pw->pw_uid;    
  86.         }
  87.     }
  88.     else {    /* User name (not a number) */
  89.         if (NULL != (pw = getpwnam(current_prot->uid_name))) {
  90.         if (TRACE) fprintf(stderr, "%s(\"%s\") %s (%s:%s:%d:%d:...)\n",
  91.                    "HTAA_getUid: getpwnam",
  92.                    current_prot->uid_name, "returned",
  93.                    pw->pw_name, pw->pw_passwd,
  94.                    pw->pw_uid, pw->pw_gid);
  95.         return pw->pw_uid;
  96.         }
  97.     }
  98.     }
  99.     return 65534;    /* nobody */
  100. }
  101.  
  102.  
  103. /* PUBLIC                            HTAA_getGid()
  104. **        GET THE GROUP ID TO CHANGE THE PROCESS GID TO
  105. ** ON ENTRY:
  106. **    No arguments.
  107. **
  108. ** ON EXIT:
  109. **    returns    the uid number to give to setgid() system call.
  110. **        Default is 65534 (nogroup).
  111. */
  112. PUBLIC int HTAA_getGid NOARGS
  113. {    
  114.     struct group *gr = NULL;
  115.     
  116.     if (current_prot  &&  current_prot->gid_name) {
  117.     if (isNumber(current_prot->gid_name)) {
  118.         if (NULL != (gr = getgrgid(atoi(current_prot->gid_name)))) {
  119.         if (TRACE) fprintf(stderr,
  120.                    "%s(%s) returned (%s:%s:%d:...)\n",
  121.                    "HTAA_getGid: getgrgid",
  122.                    current_prot->gid_name,
  123.                    gr->gr_name, gr->gr_passwd, gr->gr_gid);
  124.         return gr->gr_gid;
  125.         }
  126.     }
  127.     else {    /* Group name (not number) */
  128.         if (NULL != (gr = getgrnam(current_prot->gid_name))) {
  129.         if (TRACE) fprintf(stderr, 
  130.                    "%s(\"%s\") returned (%s:%s:%d:...)\n",
  131.                    "HTAA_getGid: getgrnam",
  132.                    current_prot->gid_name,
  133.                    gr->gr_name, gr->gr_passwd, gr->gr_gid);
  134.         return gr->gr_gid;
  135.         }
  136.     }
  137.     }
  138.     return 65534;    /* nogroup */
  139. }
  140.  
  141.  
  142.  
  143. /* PRIVATE                            HTAA_setIds()
  144. **        SET UID AND GID (AS NAMES OR NUMBERS)
  145. **        TO HTAAProt STRUCTURE
  146. ** ON ENTRY:
  147. **    prot        destination.
  148. **    ids        is a string like "james.www" or "1422.69" etc.
  149. **            giving uid and gid.
  150. **
  151. ** ON EXIT:
  152. **    returns        nothing.
  153. */
  154. PRIVATE void HTAA_setIds ARGS2(HTAAProt *,    prot,
  155.                    CONST char *,    ids)
  156. {
  157.     if (ids) {
  158.     char *local_copy = NULL;
  159.     char *point;
  160.  
  161.     StrAllocCopy(local_copy, ids);
  162.     point = strchr(local_copy, '.');
  163.     if (point) {
  164.         *(point++) = (char)0;
  165.         StrAllocCopy(prot->gid_name, point);
  166.     }
  167.     else {
  168.         StrAllocCopy(prot->gid_name, "nogroup");
  169.     }
  170.     StrAllocCopy(prot->uid_name, local_copy);
  171.     FREE(local_copy);
  172.     }
  173.     else {
  174.     StrAllocCopy(prot->uid_name, "nobody");
  175.     StrAllocCopy(prot->gid_name, "nogroup");
  176.     }
  177. }
  178.  
  179.  
  180.  
  181. /* PRIVATE                        HTAA_parseProtFile()
  182. **        PARSE A PROTECTION SETUP FILE AND
  183. **        PUT THE RESULT IN A HTAAProt STRUCTURE
  184. ** ON ENTRY:
  185. **    prot        destination structure.
  186. **    fp        open protection file.
  187. **
  188. ** ON EXIT:
  189. **    returns        nothing.
  190. */
  191. PRIVATE void HTAA_parseProtFile ARGS2(HTAAProt *, prot,
  192.                       FILE *,      fp)
  193. {
  194.     if (prot && fp) {
  195.     LexItem lex_item;
  196.     char *fieldname = NULL;
  197.  
  198.     while (LEX_EOF != (lex_item = lex(fp))) {
  199.  
  200.         while (lex_item == LEX_REC_SEP)    /* Ignore empty lines */
  201.         lex_item = lex(fp);
  202.  
  203.         if (lex_item == LEX_EOF)        /* End of file */
  204.         break;
  205.  
  206.         if (lex_item == LEX_ALPH_STR) {    /* Valid setup record */
  207.         
  208.         StrAllocCopy(fieldname, lex_buffer);
  209.         
  210.         if (LEX_FIELD_SEP != (lex_item = lex(fp)))
  211.             unlex(lex_item);    /* If someone wants to use colon */
  212.                                 /* after field name it's ok, but */
  213.                                 /* not required. Here we read it.*/
  214.  
  215.         if (0==strncasecomp(fieldname, "Auth", 4)) {
  216.             lex_item = lex(fp);
  217.             while (lex_item == LEX_ALPH_STR) {
  218.             HTAAScheme scheme = HTAAScheme_enum(lex_buffer);
  219.             if (scheme != HTAA_UNKNOWN) {
  220.                 if (!prot->valid_schemes)
  221.                 prot->valid_schemes = HTList_new();
  222.                 HTList_addObject(prot->valid_schemes,(void*)scheme);
  223.                 if (TRACE) fprintf(stderr, "%s %s `%s'\n",
  224.                            "HTAA_parseProtFile: valid",
  225.                            "authentication scheme:",
  226.                            HTAAScheme_name(scheme));
  227.             }
  228.             else if (TRACE) fprintf(stderr, "%s %s `%s'\n",
  229.                         "HTAA_parseProtFile: unknown",
  230.                         "authentication scheme:",
  231.                         lex_buffer);
  232.             
  233.             if (LEX_ITEM_SEP != (lex_item = lex(fp)))
  234.                 break;
  235.             /*
  236.             ** Here lex_item == LEX_ITEM_SEP; after item separator
  237.             ** it is ok to have one or more newlines (LEX_REC_SEP)
  238.             ** and they are ignored (continuation line).
  239.             */
  240.             do {
  241.                 lex_item = lex(fp);
  242.             } while (lex_item == LEX_REC_SEP);
  243.             } /* while items in list */
  244.         } /* if "Authenticate" */
  245.  
  246.         else if (0==strncasecomp(fieldname, "mask", 4)) {
  247.             prot->mask_group = HTAA_parseGroupDef(fp);
  248.             lex_item=LEX_REC_SEP; /*groupdef parser read this already*/
  249.             if (TRACE) {
  250.             if (prot->mask_group) {
  251.                 fprintf(stderr,
  252.                     "HTAA_parseProtFile: Mask group:\n");
  253.                 HTAA_printGroupDef(prot->mask_group);
  254.             } else fprintf(stderr, "HTAA_parseProtFile: %s\n",
  255.                        "Mask group syntax error");
  256.             }
  257.         } /* if "Mask" */
  258.  
  259.         else {    /* Just a name-value pair, put it to assoclist */
  260.  
  261.             if (LEX_ALPH_STR == (lex_item = lex(fp))) {
  262.             if (!prot->values)
  263.                 prot->values = HTAssocList_new();
  264.             HTAssocList_add(prot->values, fieldname, lex_buffer);
  265.             lex_item = lex(fp);  /* Read record separator */
  266.             if (TRACE) fprintf(stderr, 
  267.                        "%s `%s' bound to value `%s'\n",
  268.                        "HTAA_parseProtFile: Name",
  269.                        fieldname, lex_buffer);
  270.             }
  271.         } /* else name-value pair */
  272.  
  273.         } /* if valid field */
  274.  
  275.         if (lex_item != LEX_EOF  &&  lex_item != LEX_REC_SEP) {
  276.         if (TRACE) fprintf(stderr, "%s %s %d (that line ignored)\n",
  277.                    "HTAA_parseProtFile: Syntax error",
  278.                    "in protection setup file at line",
  279.                    lex_line);
  280.         do {
  281.             lex_item = lex(fp);
  282.         } while (lex_item != LEX_EOF && lex_item != LEX_REC_SEP);
  283.         } /* if syntax error */
  284.     } /* while not end-of-file */
  285.     } /* if valid parameters */
  286. }
  287.  
  288.  
  289.  
  290.  
  291. /* PRIVATE                        HTAAProt_new()
  292. **        ALLOCATE A NEW HTAAProt STRUCTURE AND
  293. **        INITIALIZE IT FROM PROTECTION SETUP FILE
  294. ** ON ENTRY:
  295. **    cur_docname    current filename after rule translations.
  296. **    prot_filename    protection setup file name.
  297. **            If NULL, not an error.
  298. **    ids        Uid and gid names or numbers,
  299. **            examples:
  300. **                james    ( <=> james.nogroup)
  301. **                .www    ( <=> nobody.www)
  302. **                james.www
  303. **                james.69
  304. **                1422.69
  305. **                1422.www
  306. **
  307. **            May be NULL, defaults to nobody.nogroup.
  308. **            Should be NULL, if prot_file is NULL.
  309. **
  310. ** ON EXIT:
  311. **    returns        returns a new and initialized protection
  312. **            setup structure.
  313. **            If setup file is already read in (found
  314. **            in cache), only sets uid_name and gid
  315. **            fields, and returns that.
  316. */
  317. PRIVATE HTAAProt *HTAAProt_new ARGS3(CONST char *,    cur_docname,
  318.                      CONST char *,    prot_filename,
  319.                      CONST char *,    ids)
  320. {
  321.     HTList *cur = prot_cache;
  322.     HTAAProtCache *cache_item = NULL;
  323.     HTAAProt *prot;
  324.     FILE *fp;
  325.  
  326.     if (!prot_cache)
  327.     prot_cache = HTList_new();
  328.     
  329.     while (NULL != (cache_item = (HTAAProtCache*)HTList_nextObject(cur))) {
  330.     if (!strcmp(cache_item->prot_filename, prot_filename))
  331.         break;
  332.     }
  333.     if (cache_item) {
  334.     prot = cache_item->prot;
  335.     if (TRACE) fprintf(stderr, "%s `%s' already in cache\n",
  336.                "HTAAProt_new: Protection file", prot_filename);
  337.     } else {
  338.     if (TRACE) fprintf(stderr,
  339.                "HTAAProt_new: Loading protection file `%s'\n",
  340.                prot_filename);
  341.  
  342.     if (!(prot = (HTAAProt*)malloc(sizeof(HTAAProt))))
  343.         outofmem(__FILE__, "HTAAProt_new");
  344.  
  345.     prot->template    = NULL;
  346.     prot->filename    = NULL;
  347.     prot->uid_name    = NULL;
  348.     prot->gid_name    = NULL;
  349.     prot->valid_schemes = HTList_new();
  350.     prot->mask_group= NULL;        /* Masking disabled by defaults */
  351.     prot->values    = HTAssocList_new();
  352.  
  353.     if (prot_filename && NULL != (fp = fopen(prot_filename, "r"))) {
  354.         HTAA_parseProtFile(prot, fp);
  355.         fclose(fp);
  356.         if (!(cache_item = (HTAAProtCache*)malloc(sizeof(HTAAProtCache))))
  357.         outofmem(__FILE__, "HTAAProt_new");
  358.         cache_item->prot = prot;
  359.         cache_item->prot_filename = NULL;
  360.         StrAllocCopy(cache_item->prot_filename, prot_filename);
  361.         HTList_addObject(prot_cache, (void*)cache_item);
  362.     }
  363.     else if (TRACE) fprintf(stderr, "HTAAProt_new: %s `%s'\n",
  364.                 "Unable to open protection setup file",
  365.                 (prot_filename ? prot_filename : "(null)"));
  366.     }
  367.  
  368.     if (cur_docname)
  369.     StrAllocCopy(prot->filename, cur_docname);
  370.     HTAA_setIds(prot, ids);
  371.  
  372.     return prot;
  373. }
  374.  
  375.  
  376.  
  377. /* PUBLIC                    HTAA_setDefaultProtection()
  378. **        SET THE DEFAULT PROTECTION MODE
  379. **        (called by rule system when a
  380. **        "defprot" rule is matched)
  381. ** ON ENTRY:
  382. **    cur_docname    is the current result of rule translations.
  383. **    prot_filename    is the protection setup file (second argument
  384. **            for "defprot" rule, optional)
  385. **    ids        contains user and group names separated by
  386. **            a dot, corresponding to the uid
  387. **            gid under which the server should run,
  388. **            default is "nobody.nogroup" (third argument
  389. **            for "defprot" rule, optional; can be given
  390. **            only if protection setup file is also given).
  391. **
  392. ** ON EXIT:
  393. **    returns        nothing.
  394. **            Sets the module-wide variable default_prot.
  395. */
  396. PUBLIC void HTAA_setDefaultProtection ARGS3(CONST char *,    cur_docname,
  397.                         CONST char *,    prot_filename,
  398.                         CONST char *,    ids)
  399. {
  400.     default_prot = NULL;    /* Not free()'d because this is in cache */
  401.  
  402.     if (prot_filename) {
  403.     default_prot = HTAAProt_new(cur_docname, prot_filename, ids);
  404.     } else {
  405.     if (TRACE) fprintf(stderr, "%s %s\n",
  406.                "HTAA_setDefaultProtection: ERROR: Protection file",
  407.                "not specified (obligatory for DefProt rule)!!\n");
  408.     }
  409. }
  410.  
  411.  
  412.  
  413. /* PUBLIC                    HTAA_setCurrentProtection()
  414. **        SET THE CURRENT PROTECTION MODE
  415. **        (called by rule system when a
  416. **        "protect" rule is matched)
  417. ** ON ENTRY:
  418. **    cur_docname    is the current result of rule translations.
  419. **    prot_filename    is the protection setup file (second argument
  420. **            for "protect" rule, optional)
  421. **    ids        contains user and group names separated by
  422. **            a dot, corresponding to the uid
  423. **            gid under which the server should run,
  424. **            default is "nobody.nogroup" (third argument
  425. **            for "protect" rule, optional; can be given
  426. **            only if protection setup file is also given).
  427. **
  428. ** ON EXIT:
  429. **    returns        nothing.
  430. **            Sets the module-wide variable current_prot.
  431. */
  432. PUBLIC void HTAA_setCurrentProtection ARGS3(CONST char *,    cur_docname,
  433.                         CONST char *,    prot_filename,
  434.                         CONST char *,    ids)
  435. {
  436.     current_prot = NULL;    /* Not free()'d because this is in cache */
  437.  
  438.     if (prot_filename) {
  439.     current_prot = HTAAProt_new(cur_docname, prot_filename, ids);
  440.     } else {
  441.     if (default_prot) {
  442.         current_prot = default_prot;
  443.         HTAA_setIds(current_prot, ids);
  444.         if (TRACE) fprintf(stderr, "%s %s %s\n",
  445.                    "HTAA_setCurrentProtection: Protection file",
  446.                    "not specified for Protect rule",
  447.                    "-- using default protection");
  448.     } else {
  449.         if (TRACE) fprintf(stderr, "%s %s %s\n",
  450.                    "HTAA_setCurrentProtection: ERROR: Protection",
  451.                    "file not specified for Protect rule, and",
  452.                    "default protection is not set!!");
  453.     }
  454.     }
  455. }
  456.  
  457.  
  458.  
  459. /* PUBLIC                    HTAA_getCurrentProtection()
  460. **        GET CURRENT PROTECTION SETUP STRUCTURE
  461. **        (this is set up by callbacks made from
  462. **         the rule system when matching "protect"
  463. **         (and "defprot") rules)
  464. ** ON ENTRY:
  465. **    HTTranslate() must have been called before calling
  466. **    this function.
  467. **
  468. ** ON EXIT:
  469. **    returns    a HTAAProt structure representing the
  470. **        protection setup of the HTTranslate()'d file.
  471. **        This must not be free()'d.
  472. */
  473. PUBLIC HTAAProt *HTAA_getCurrentProtection NOARGS
  474. {
  475.     return current_prot;
  476. }
  477.  
  478.  
  479.  
  480. /* PUBLIC                    HTAA_getDefaultProtection()
  481. **        GET DEFAULT PROTECTION SETUP STRUCTURE
  482. **        AND SET IT TO CURRENT PROTECTION
  483. **        (this is set up by callbacks made from
  484. **         the rule system when matching "defprot"
  485. **         rules)
  486. ** ON ENTRY:
  487. **    HTTranslate() must have been called before calling
  488. **    this function.
  489. **
  490. ** ON EXIT:
  491. **    returns    a HTAAProt structure representing the
  492. **        default protection setup of the HTTranslate()'d
  493. **        file (if HTAA_getCurrentProtection() returned
  494. **        NULL, i.e. if there is no "protect" rule
  495. **        but ACL exists, and we need to know default
  496. **        protection settings).
  497. **        This must not be free()'d.
  498. ** IMPORTANT:
  499. **    As a side-effect this tells the protection system that
  500. **    the file is in fact protected and sets the current
  501. **    protection mode to default.
  502. */
  503. PUBLIC HTAAProt *HTAA_getDefaultProtection NOARGS
  504. {
  505.     if (!current_prot) {
  506.     current_prot = default_prot;
  507.     default_prot = NULL;
  508.     }    
  509.     return current_prot;
  510. }
  511.  
  512.  
  513.  
  514. /* SERVER INTERNAL                    HTAA_clearProtections()
  515. **        CLEAR DOCUMENT PROTECTION MODE
  516. **        (ALSO DEFAULT PROTECTION)
  517. **        (called by the rule system)
  518. ** ON ENTRY:
  519. **    No arguments.
  520. **
  521. ** ON EXIT:
  522. **    returns    nothing.
  523. **        Frees the memory used by protection information.
  524. */
  525. PUBLIC void HTAA_clearProtections NOARGS
  526. {
  527.     current_prot = NULL;    /* These are not freed because    */
  528.     default_prot = NULL;    /* they are actually in cache.    */
  529. }
  530.  
  531.  
  532.